home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / Arch / Sparc / audio.c next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  6.6 KB  |  331 lines

  1. /* sparc/audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: audio.c,v 4.3 1995/02/01 16:43:47 espie Exp $
  6.  * $Log: audio.c,v $
  7.  * Revision 4.3  1995/02/01  16:43:47  espie
  8.  * 23 bit samples.
  9.  *
  10.  * Revision 4.3  1995/02/01  16:43:47  espie
  11.  * 23 bit samples.
  12.  *
  13.  * Revision 4.2  1994/01/13  09:19:08  espie
  14.  * Forgotten something.
  15.  *
  16.  * Revision 4.0  1994/01/11  18:16:36  espie
  17.  * New release.
  18.  *
  19.  * Revision 1.2  1993/12/26  18:54:21  Espie
  20.  * Handle errors better.
  21.  *
  22.  * Revision 1.1  1993/12/26  00:55:53  Espie
  23.  * Initial revision
  24.  *
  25.  * Revision 3.14  1993/12/04  16:12:50  espie
  26.  * BOOL -> boolean.
  27.  *
  28.  * Revision 3.13  1993/12/02  15:45:33  espie
  29.  * Merged ss10/solaris.
  30.  *
  31.  * Revision 3.12  1993/11/27  17:07:33  espie
  32.  * Merged support for solaris together.
  33.  *
  34.  * Revision 3.11  1993/11/17  15:31:16  espie
  35.  * *** empty log message ***
  36.  *
  37.  *
  38.  * Revision 3.9  1993/07/14  16:33:41  espie
  39.  * Fixed /16 bug.
  40.  *
  41.  * Revision 3.8  1993/05/09  14:06:03  espie
  42.  * Corrected mix problem.
  43.  *
  44.  * Revision 3.6  1992/12/03  15:00:50  espie
  45.  * restore stty.
  46.  *
  47.  * Revision 3.4  1992/11/24  10:51:19  espie
  48.  * Sync pseudo call.
  49.  *
  50.  * Revision 3.3  1992/11/22  17:20:01  espie
  51.  * Added update_frequency call, mostly unchecked
  52.  *
  53.  * Revision 3.2  1992/11/20  14:53:32  espie
  54.  * Added finetune.
  55.  *
  56.  * Revision 3.1  1992/11/19  20:44:47  espie
  57.  * Protracker commands.
  58.  *
  59.  * Revision 3.0  1992/11/18  16:08:05  espie
  60.  * New release.
  61.  *
  62.  * Revision 1.3  1992/11/17  15:38:00  espie
  63.  * discard_buffer() call for snappier interface calls.
  64.  * - Unified support for all sparcs.
  65.  * - moved down to level 2 io.
  66.  */
  67.  
  68. #include "defs.h"
  69. #include "extern.h"
  70. #ifdef SOLARIS
  71. #include <sys/audio.io.h>
  72. #else
  73. #include <sun/audioio.h>
  74. #endif
  75. #include <sys/ioctl.h>
  76. #include <fcntl.h>
  77. #include <stropts.h>
  78.      
  79. /* things that aren't defined in all sun/audioio.h */
  80.  
  81. #ifndef AUDIO_ENCODING_LINEAR
  82. #define AUDIO_ENCODING_LINEAR (3)
  83. #endif
  84. #ifndef AUDIO_GETDEV
  85. #define AUDIO_GETDEV    _IOR(A, 4, int)
  86. #endif
  87. #ifndef AUDIO_DEV_UNKNOWN
  88. #define AUDIO_DEV_UNKNOWN (0)
  89. #endif
  90. #ifndef AUDIO_DEV_AMD
  91. #define AUDIO_DEV_AMD (1)
  92. #endif
  93.  
  94. ID("$Id: audio.c,v 4.3 1995/02/01 16:43:47 espie Exp $")
  95.  
  96. LOCAL int audio;
  97.  
  98. LOCAL struct audio_info ainfo;
  99. LOCAL char *buffer;
  100. LOCAL short *sbuffer;
  101. LOCAL int index;
  102. LOCAL int dsize;
  103.  
  104. LOCAL int stereo;
  105. LOCAL int primary, secondary;
  106.  
  107. void set_mix(percent)
  108. int percent;
  109.     {
  110.     percent *= 256;
  111.     percent /= 100;
  112.     primary = percent;
  113.     secondary = 512 - percent;
  114.     }
  115.  
  116. #define abs(x) ((x) < 0 ? -(x) : (x))
  117.  
  118. LOCAL int available(f)
  119. int f;
  120.     {
  121.     static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
  122.         37800, 44100, 48000, 0};
  123.     int best = 8000;
  124.     int i;
  125.  
  126.     for (i = 0; possible[i]; i++)
  127.         if (abs(possible[i] - f) < abs(best - f))
  128.             best = possible[i];
  129.     return best;
  130.     }
  131.  
  132. int open_audio(f, s)
  133. int f;
  134. int s;
  135.     {
  136.     int type;
  137.     int basic;
  138. #ifdef SOLARIS
  139.     audio_device_t dev;
  140.  
  141.     audio = open("/dev/audio", O_WRONLY);
  142. #else
  143.     audio = open("/dev/audio", O_WRONLY|O_NDELAY);
  144. #endif
  145.  
  146.  
  147.     basic = 0;
  148.     if (audio == -1)
  149.         end_all("Error: could not open audio");
  150.     if (f == 0)
  151.         f = 22050;
  152.         /* round frequency to acceptable value */
  153.     f = available(f);
  154.  
  155.         /* check whether we know about AUDIO_ENCODING_LINEAR */
  156. #ifdef SOLARIS
  157.     ioctl(audio, AUDIO_GETDEV, &dev);
  158.     if (strcmp(dev.name, "SUNW,dbri") != 0)
  159. #else
  160.     if (ioctl(audio, AUDIO_GETDEV, &type) ||
  161.     type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD || basic)
  162. #endif
  163.         {
  164.             /* not a new ss5/10/20 -> revert to base quality audio */
  165.         stereo = 0;
  166.         dsize = 1;
  167.         ainfo.play.sample_rate = 8000;
  168.         ainfo.play.encoding = AUDIO_ENCODING_ULAW;
  169.         ainfo.play.channels = 1;
  170.         puts("Basic");
  171.         }
  172.     else
  173.         {
  174.             /* tentative set up */
  175.         stereo = s;
  176.         AUDIO_INITINFO(&ainfo);
  177.         ainfo.play.sample_rate = f;
  178.         ainfo.play.precision = 16;
  179.         dsize = 2;
  180.         if (stereo)
  181.             {
  182.             ainfo.play.channels = 2;
  183.             }
  184.         else
  185.             ainfo.play.channels = 1;
  186.             /* try it */
  187.         ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
  188.         if (ioctl(audio, AUDIO_SETINFO, &ainfo) != 0)
  189.             /* didn't work: fatal problem */
  190.             end_all("Error: AUDIO_SETINFO");
  191.         }
  192.     index = 0;
  193.     buffer = (char *)malloc(dsize * ainfo.play.channels * ainfo.play.sample_rate);
  194.     sbuffer = (short *) buffer;
  195.     if (!buffer)
  196.         end_all("Error: could not allocate buffer");
  197.     return ainfo.play.sample_rate;
  198.     }
  199.  
  200. void set_synchro(s)
  201. int s;
  202.     {
  203.     }
  204.  
  205. int update_frequency()
  206.     {
  207.     int oldfreq;
  208.  
  209.     oldfreq = ainfo.play.sample_rate;
  210.     if (ioctl(audio, AUDIO_GETINFO, &ainfo) == 0)
  211.         {
  212.         if (oldfreq != ainfo.play.sample_rate)
  213.             {
  214.             buffer = realloc(buffer, 
  215.                 dsize * ainfo.play.channels * ainfo.play.sample_rate);
  216.             sbuffer = (short *)buffer;
  217.             return ainfo.play.sample_rate;
  218.             }
  219.         }
  220.     return 0;
  221.     }
  222.  
  223.  
  224. LOCAL int sign(x)
  225. unsigned char x;
  226.     {
  227.     return x;
  228.     }
  229.  
  230. /************************************************************************/
  231. /*      For routine 'cvt' only                                          */
  232. /************************************************************************/
  233. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  234. /************************************************************************/
  235.  
  236. LOCAL unsigned int cvt(ch)
  237. int ch;
  238.     {
  239.     int mask;
  240.  
  241.     if (ch < 0)
  242.         {
  243.         ch = -ch;
  244.         mask = 0x7f;
  245.         }
  246.     else
  247.         mask = 0xff;
  248.  
  249.     if (ch < 32)
  250.         {
  251.         ch = 0xF0 | 15 - (ch / 2);
  252.         }
  253.     else if (ch < 96)
  254.         {
  255.         ch = 0xE0 | 15 - (ch - 32) / 4;
  256.         }
  257.     else if (ch < 224)
  258.         {
  259.         ch = 0xD0 | 15 - (ch - 96) / 8;
  260.         }
  261.     else if (ch < 480)
  262.         {
  263.         ch = 0xC0 | 15 - (ch - 224) / 16;
  264.         }
  265.     else if (ch < 992)
  266.         {
  267.         ch = 0xB0 | 15 - (ch - 480) / 32;
  268.         }
  269.     else if (ch < 2016)
  270.         {
  271.         ch = 0xA0 | 15 - (ch - 992) / 64;
  272.         }
  273.     else if (ch < 4064)
  274.         {
  275.         ch = 0x90 | 15 - (ch - 2016) / 128;
  276.         }
  277.     else if (ch < 8160)
  278.         {
  279.         ch = 0x80 | 15 - (ch - 4064) /  256;
  280.         }
  281.     else
  282.         {
  283.         ch = 0x80;
  284.         }
  285.     return (mask & ch);
  286.     }
  287.  
  288.  
  289. void output_samples(left, right)
  290. int left, right;
  291.     {
  292.     if (stereo)
  293.         {
  294.         sbuffer[index++] = (left * primary + right * secondary)/65536;
  295.         sbuffer[index++] = (right * primary + left * secondary)/65536;
  296.         }
  297.     else
  298.         switch(ainfo.play.encoding)
  299.             {
  300.         case AUDIO_ENCODING_LINEAR:
  301.             sbuffer[index++] = (left + right)/256;
  302.             break;
  303.         case AUDIO_ENCODING_ULAW:
  304.             buffer[index++] = cvt((left + right) /1024);
  305.             break;
  306.             }
  307.     }
  308.  
  309. void flush_buffer()
  310.     {
  311.     int actual;
  312.  
  313.     actual = write(audio, buffer, dsize * index);
  314.     if (actual == -1)
  315.         notice("Write to audio failed");
  316.     else if (actual != dsize * index)
  317.         notice("Short write to audio");
  318.     index = 0;
  319.     }
  320.  
  321. void discard_buffer()
  322.     {
  323.     ioctl(audio, I_FLUSH, FLUSHW);
  324.     }
  325.  
  326. void close_audio()
  327.     {
  328.     free(buffer);
  329.     close(audio);
  330.     }
  331.